home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / answrbok / 3_11.lha / 3_11 / 3_11b.c < prev    next >
Text File  |  1993-08-08  |  2KB  |  114 lines

  1. * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
  2. * The C++ Answer Book */
  3. * Tony Hansen */
  4. * All rights reserved. */
  5. / Convert a string of signed digits into an integer.
  6. / Hex and octal prefixes are allowed.
  7. /  Version 2
  8. define NO_ISODIGIT    /* DELETE */
  9. include <ctype.h>
  10. include <limits.h>
  11. include <error.h>
  12.  
  13. / convert hexadecimal 0-9, a-f, A-F
  14. / to its numeric value
  15. nline int hexvalue(char c)
  16.  
  17.    if (isdigit(c))
  18. return c - '0';
  19.  
  20.    else if (c >= 'a' && c <= 'f')
  21. return c - 'a' + 10;
  22.  
  23.    else /* (c >= 'A' && c <= 'F') */
  24. return c - 'A' + 10;
  25.  
  26.  
  27. / return true if c is an octal digit
  28. nline int isodigit(char c)
  29.  
  30.    return isdigit(c) && c < '8';
  31.  
  32.  
  33. include "3_11e1.c"    /* EXPAND defines TWOSCOMPLEMENT */
  34.  
  35. nt atoi(const char *s)
  36.  
  37.    char sign = 0;
  38.    int i = 0;
  39.  
  40.    switch (*s)        // remember the sign
  41. {
  42. case '+':
  43. case '-':
  44.     sign = *s++;
  45.     break;
  46. }
  47.  
  48.    // for positive numbers on a 2's complement machine,
  49.    // the minimum # is -INT_MAX, not INT_MIN
  50.    const int int_min = (TWOSCOMPLEMENT && (sign != '-')) ?
  51.         (-INT_MAX) : INT_MIN;
  52.  
  53.    switch (*s)
  54. {
  55. case '0':        // hex or octal
  56.     switch (*++s)
  57.     {
  58.     case 'x':        // hex number
  59.     case 'X':
  60.         for (s++; isxdigit(*s); s++)
  61.         {
  62.         if (-i > INT_MAX / 16)
  63.             break;
  64.         i *= 16;
  65.         int n = hexvalue(*s);
  66.         if (i < int_min + n)
  67.             break;
  68.         i -= n;
  69.         }
  70.  
  71.         if (isxdigit(*s))
  72.         error("integer overflow");
  73.         break;
  74.  
  75.     default:        // octal number
  76.         for ( ; isodigit(*s); s++)
  77.         {
  78.         if (-i > INT_MAX / 8)
  79.             break;
  80.         i *= 8;
  81.         int n = *s - '0';
  82.         if (i < int_min + n)
  83.             break;
  84.         i -= n;
  85.         }
  86.  
  87.         if (isodigit(*s))
  88.         error("integer overflow");
  89.         break;
  90.     }
  91.     break;
  92.  
  93. default:        // decimal number
  94.     for ( ; isdigit(*s); s++)
  95.     {
  96.     if (-i > INT_MAX / 10)
  97.         break;
  98.     i *= 10;
  99.     int n = *s - '0';
  100.     if (i < int_min + n)
  101.         break;
  102.     i -= n;
  103.     }
  104.  
  105.     if (isdigit(*s))
  106.     error("integer overflow");
  107.     break;
  108. }
  109.  
  110.    if (*s)
  111. error("malformed integer");
  112.    return sign == '-' ? i : -i;
  113.  
  114.